你们公司还在用SparkOnYan吗?
1
背景
spark部署模型有以下几种:
独立模式,Spark原生的简单集群管理器,自带完整的服务,可单独部署到一个集群中,无需依赖任何其他资源管理系统,使用Standalone可以很方便地搭建一个集群
一个强大的分布式资源管理框架,它允许多种不同的框架部署在其上
统一的资源管理机制,在上面可以运行多套计算框架,如map reduce、storm等,根据driver在集群中的位置不同,分为yarn client和yarn cluster
由于在实际生产环境中中,都会使用hadoop集群,所以一般都会使用sparkOnYarn的模式。把spark的任务,提交给yarn平台来调度
集群环境准备
需要在/etc/profile中配置HADOOP_CONF_DIR的目录,目的是为了让Spark找到core-site.xml、hdfs-site.xml和yarn-site.xml【让spark知道NameNode、ResourceManager】,不然会报如下错误:
Exception in thread "main" java.lang.Exception: When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment.
关闭内存资源检测(vim yarn-site.xml)
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
yarn.nodemanager.pmem-check-enabled
是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true。yarn.nodemanager.vmem-check-enabled
是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true。如果不关闭,在spark on yarn的client模式下,可能会出现内存不足导致任务被杀死。
配置一个yarn的container可以使用多个vcores,因为capacity schedule使用的是DefaultResourceCalculator,那么DefaultResourceCalculator它在加载Container时其实仅仅只会考虑内存而不考虑vcores,默认vcore就是1。yarn 默认情况下,只根据内存调度资源,所以 spark on yarn 运行的时候,即使通过--executor-cores 指定 core 个数为 N,但是在 yarn 的资源管理页面上看到使用的 vcore 个数还是 1
vim capacity-scheduler.xml
<property>
<name>yarn.scheduler.capacity.resource-calculator</name>
<value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
</property>
客户端配置
需要spark安装包
客户端能和hadoop集群通信(hdfs + yarn) 有hadoop的安装配置
sparkOnYarn任务提交(基于spark2.x)
/usr/local/spark2.3/bin/spark-submit \
--class com.test.Application \
--master yarn \
--deploy-mode client \
--driver-memory 4g \
--executor-memory 5g \
--queue dw \
--num-executors 60 \
--jars /home/hadoop/liuzc/config-1.3.0.jar
任务运行过程中,客户端不能退出,否则任务失败,并且结果在客户端展示
执行流程:
客户端提交一个Application,在客户端启动一个Driver进程。
Driver进程会向ResourceManager发送请求,启动ApplicationMaster的资源。
ResourceManager收到请求,随机选择一台NodeManager,然后该NodeManager到HDFS下载jar包和配置,接着启动ApplicationMaster【ExecutorLuacher】。这里的NodeManager相当于Standalone中的Worker节点。
ApplicationMaster启动后,会向ResourceManager请求一批container资源,用于启动Executor.
ResourceManager会找到一批符合条件NodeManager返回给ApplicationMaster,用于启动Executor。
ApplicationMaster会向NodeManager发送请求,NodeManager到HDFS下载jar包和配置,然后启动Executor。
Executor启动后,会反向注册给Driver,Driver发送task到Executor,执行情况和结果返回给Driver端
/usr/local/spark2.3/bin/spark-submit \
--class com.test.Application \
--master yarn \
--deploy-mode cluster\
--driver-memory 4g \
--executor-memory 5g \
--queue dw \
--num-executors 60 \
--jars /home/hadoop/liuzc/config-1.3.0.jar
driver运行在集群中的某一个节点,driver如果挂掉了,还可以重启
客户端仅仅负责提交任务,一定任务成功提交到集群中,客户端可以退出并且结果在集群中展示
执行流程:
client向ResouceManager申请资源,返回一个applicationID
client上传spark jars下面的jar包,自己写的jar和配置
ResourceManager随机找一个资源充足的NodeManager
然后通过RPC让NodeManager从HDFS上下载jar包和配置,启动ApplicationMaster
ApplicationMaster向ResourceManager申请资源
ResourceManager中的ResourceScheduler找到符合条件的NodeManager,将NodeManager的信息返回给ApplicationMaster
ApplicationMaster和返回的NodeManager进行通信
NodeManager从HDFS下载依赖
NodeManager启动Executor
Executor启动之后反向向ApplicationMaster(Driver)注册
对比
SparkContext初始化不同,这也导致了Driver所在位置的不同。
Yarn-cluster的driver是在集群节点中随机选取启动,Yarn-client的driver端是在任务提交的客户端找中启动。
而Driver会和Executors进行通信,这也导致了Yarn-Cluster在提交App之后可以关闭Client,而Yarn-Client不可以
最后再来说应用场景,Yarn-Cluster适合生产环境,Yarn-Client适合交互和调试(少部分需要收集返回结果的场景也用client模式)